﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Hiro.ActivationPoints.Interfaces;
using Hiro.Interfaces;
using Hiro.Loaders.Interfaces;

namespace Hiro.Loaders
{
    internal class ServiceBuilder : IServiceBuilder
    {
        private readonly IServiceResolver _resolver;
        public ServiceBuilder()
            : this(new ServiceResolver())
        {
        }
        public ServiceBuilder(IServiceResolver resolver)
        {
            _resolver = resolver;
        }

        public IList<IService> GetServices(IDictionary<IDependency, IList<ITypeActivationPoint>> serviceMap)
        {
            // Dependencies that have only one implementation will automatically be converted into services
            var services = (from dependency in serviceMap.Keys
                            where serviceMap[dependency].Count == 1
                            select new Service(dependency,
                                               serviceMap[dependency].First()) as IService).ToList();

            // Interfaces that have more than one implementation will
            // have to be resolved by the service resolver
            var ambiguousDependencies = from dependency in serviceMap.Keys
                                        where serviceMap[dependency].Count > 1
                                        select dependency;

            foreach (var dependency in ambiguousDependencies)
            {
                var serviceType = dependency.ServiceType;
                var points = serviceMap[dependency];
                var resolvedServices = _resolver.Resolve(serviceType, points);

                if (resolvedServices.Count() == 0)
                    continue;

                services.AddRange(resolvedServices);
            }

            return services;
        }
    }
}
